﻿using IntegralLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HeatConductivityEquationLib
{
    /// <summary>
    /// Класс - решение для уравнения теплопроводности.
    /// </summary>
    public class HeatConductivityEquation
    {
        readonly double _low, _high, _A2;
        Function _f;
        double _x, _t;

        /// <summary>
        /// Конструктор.
        /// </summary>
        /// <param name="f">Функция вида y=f(x), первоначальное распределение тепла в стержне.</param>
        /// <param name="low">Нижний предел интегрирования.</param>
        /// <param name="high">Верхний предел интегрирования.</param>
        /// <param name="A2">Параметр уравнения теплопроводности.</param>
        public HeatConductivityEquation(double low, double high, double A2)
        {
            _low = low;
            _high = high;
            _A2 = A2;
        }

        /// <summary>
        /// Подинтегральная функция для уравнения теплопроводности.
        /// </summary>
        /// <param name="s">Переменная для интегрирования.</param>
        /// <returns>Значение подинтегральной функции в точке s.</returns>
        private double UnderIntegralExpression(double s)
        {
            double arge = -(_x - s) * (_x - s) / (4 * _A2 * _t);
            return _f(s) * Math.Exp(arge);
        }

        /// <summary>
        /// Вычисление значения функции решения уравнения теплопроводности при заданных x и t.
        /// </summary>
        /// <param name="x">Независимая переменная.</param>
        /// <param name="t">Время.</param>
        /// <returns>Значения функции решения уравнения теплопроводности при заданных x и t.</returns>
        public double HeatConductivity(double x, double t)
        {
            double u;

            if (t > 0.04)
            {
                double m = 1.0 / (2 * Math.Sqrt(Math.PI * _A2 * t));
                _x = x;
                _t = t;

                u = m * Integral.GetParallel(UnderIntegralExpression, _low, _high, 800);
            }
            else
            {
                u = _f(x);
            }

            return u;
        }

        public Function F
        {
            get { return _f; }
            set { _f = value; }
        }
    }
}
